'use strict';

import { loadShaderFromFile } from '../../../lib/js/tool-utils.js';
import webglUtils from '../../../lib/js/webgl-utils.js';

async function main() {
  // gl上下文
  const canvas = document.querySelector('#c');
  const gl = canvas.getContext('webgl2');
  if (!gl) {
    return;
  }
  const vs = await loadShaderFromFile('./glsl/2D.vert');
  const fs = await loadShaderFromFile('./glsl/2D.frag');

  const program = webglUtils.createProgramFromSources(gl, [vs, fs]);

  // GLSL程序唯一的输入属性是a_position。我们做的第一件事就是查找这个属性的位置。
  const a_position_Location = gl.getAttribLocation(program, 'a_position');

  const resolution_Uniform_Location = gl.getUniformLocation(program, 'u_resolution');

  // 属性从缓存区中取数据，所以我们需要创建缓冲区。
  const positionBuffer = gl.createBuffer();

  // WebGL通过绑定点来处理许多WebGL资源。
  // 你可以认为绑定点是WebGL内部的全局变量。
  // 首先你绑定一个资源到某个绑定点，然后所有方法通过这个绑定点来对这个资源的访问。
  gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);

  // 现在我们通过绑定点把数据存放到缓冲区。gl.STATIC_DRAW 告诉WebGL我们不太可能去改变数据的值。
  const positions = [10, 20, 80, 20, 10, 30, 10, 30, 80, 20, 80, 30];
  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);

  // 数据存放到缓存区后，接下来需要告诉属性如何从缓冲区取出数据。顶点数组对象(Vertex Array Object)。
  const vao = gl.createVertexArray();

  // 为了使所有属性的设置能够应用到WebGL属性状态集，我们需要绑定这个顶点数组到WebGL。
  gl.bindVertexArray(vao);

  // 启用属性。如果没有开启这个属性，这个属性值会是一个常量。
  gl.enableVertexAttribArray(a_position_Location);

  // 设置属性值如何从缓存区取出数据。
  const size = 2; // 2个
  const type = gl.FLOAT; // 数据类型
  const normalize = false; // don't normalize the data
  const stride = 0; // 0 = move forward size * sizeof(type) each iteration to get the next position
  let offset = 0; // start at the beginning of the buffer
  // gl.vertexAttribPointer 的隐含部分是它绑定当前的ARRAY_BUFFER到这个属性。
  gl.vertexAttribPointer(a_position_Location, size, type, normalize, stride, offset);

  webglUtils.resizeCanvasToDisplaySize(gl.canvas);

  // WebGL如何从clip space转换值转换到屏幕空间（pixels）。 为此，我们调用gl.viewport并将其传递给画布的当前大小。
  // 告诉WebGL将裁剪空间的-1~+1映射到x轴0~gl.canvas.width和y轴0~gl.canvas.height。
  gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);

  // canvas 画布清除 画布是透明的
  gl.clearColor(0, 0, 0, 0);
  gl.clear(gl.COLOR_BUFFER_BIT);

  // 告诉WebGL运行着色器程序
  gl.useProgram(program);

  // 告诉它用哪个缓冲区和如何从缓冲区取出数据给到属性。
  gl.bindVertexArray(vao);

  gl.uniform2f(resolution_Uniform_Location, gl.canvas.width, gl.canvas.height);

  // 运行GLSL程序。
  const primitiveType = gl.TRIANGLES;
  offset = 0;
  const count = 6;
  gl.drawArrays(primitiveType, offset, count);
}

main();
